package statistics;

import com.mongodb.*;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class StatisticsOneTra {

    public static void main(String[] args) {
        StatisticsOneTra statistics = new StatisticsOneTra();
//        Map map = statistics.statisticsSrc();
//        statistics.statisticsNoSrc(map);
//        Map<String, Double> map = new HashMap<>();
//        map.put("before",0.5416666666666666);
//        map.put("after",2.1666666666666665);
        statistics.statisticsNoSrc();
    }

    private void statisticsNoSrc() {
        long start = System.currentTimeMillis();
        // 创建Mongo连接
        List<ServerAddress> serverAddressList = new ArrayList<>();
        ServerAddress address = new ServerAddress("192.168.8.147", 21234);
        serverAddressList.add(address);
        MongoCredential mongoCredential = MongoCredential.createCredential("root", "admin", "jhmk123456".toCharArray());
        MongoClient client = new MongoClient(serverAddressList,mongoCredential, getOptions());

        // 准备好需要写入的库
        MongoDatabase local_test_new = client.getDatabase("local_test_new");
        MongoCollection<Document> dataCenterStatisticsDate = local_test_new.getCollection("data_center_statistics_date");
        MongoCollection<Document> nosrc = local_test_new.getCollection("nosrc");

//        new Document("$or",)new Document("_id", new Document("$regex","menzhenjianchabaogao"))
        List<Document> find_doc = new ArrayList<>();
        find_doc.add(new Document("_id",new Document("$regex","menzhenjianchabaogao")));
        find_doc.add(new Document("_id",new Document("$regex","menzhenbinglibaogao")));
        find_doc.add(new Document("_id",new Document("$regex","jianchabaogao")));
        find_doc.add(new Document("_id",new Document("$regex","binglibaogao")));
        find_doc.add(new Document("_id",new Document("$regex","menzhenjianyanbaogao")));
        find_doc.add(new Document("_id",new Document("$regex","menzhenweishengwujianyan")));
        find_doc.add(new Document("_id",new Document("$regex","jianyanbaogao")));
        find_doc.add(new Document("_id",new Document("$regex","weishengwujianyanbaogao")));
        find_doc.add(new Document("_id",new Document("$regex","menzhenxiyichufang")));
        find_doc.add(new Document("_id",new Document("$regex","yizhu")));
        find_doc.add(new Document("_id",new Document("$regex","menzhenshoushujilu")));
        find_doc.add(new Document("_id",new Document("$regex","shouyeshoushu")));
        MongoCursor<Document> iter = nosrc.find(new Document("$or",find_doc))
                .projection(new Document("_id",1)
                        .append("menzhenjianchabaogao.exam_report.exam_time",1)
                        .append("menzhenjianchabaogao.exam_report.norm_exam_class_name",1)
                        .append("menzhenbinglibaogao.pathology_report.exam_time",1)
                        .append("menzhenbinglibaogao.pathology_report.norm_exam_class_name",1)
                        .append("jianchabaogao.exam_report.exam_time",1)
                        .append("jianchabaogao.exam_report.norm_exam_class_name",1)
                        .append("binglibaogao.pathology_report.exam_time",1)
                        .append("binglibaogao.pathology_report.norm_exam_class_name",1)
                        .append("menzhenjianyanbaogao.lab_report.report_time",1)
                        .append("menzhenjianyanbaogao.lab_report.norm_lab_item_name",1)
                        .append("menzhenweishengwujianyan.lab_report.report_time",1)
                        .append("menzhenweishengwujianyan.lab_report.norm_lab_item_name",1)
                        .append("jianyanbaogao.lab_report.report_time",1)
                        .append("jianyanbaogao.lab_report.norm_lab_item_name",1)
                        .append("weishengwujianyanbaogao.lab_report.report_time",1)
                        .append("weishengwujianyanbaogao.lab_report.norm_lab_item_name",1)
                        .append("menzhenxiyichufang",1)
//                        .append("menzhenxiyichufang.order_begin_time",1)
//                        .append("menzhenxiyichufang.china_approved_drug_name",1)
                        .append("yizhu.order_begin_time",1)
                        .append("yizhu.china_approved_drug_name",1)
                        .append("menzhenshoushujilu.operation_time",1)
                        .append("menzhenshoushujilu.operation_name",1)
                        .append("shouyeshoushu.operation_date",1)
                        .append("shouyeshoushu.operation_name",1)
                        .append("shouyeshoushu.operation_type",1)
                )
                .batchSize(50).iterator();

        // combineDataMap<20231026100000#@#检查-门诊#@#手术名,sum>
        HashMap<String, Integer> combineDataMap = new HashMap<>();

        int cnt = 0;
        while (iter.hasNext()){
            long end = System.currentTimeMillis();
            System.out.println("已处理" + cnt++ + "条数据,耗时:" + (end-start)/1000 + "秒");
            Document document = iter.next();
            String type = "";
            // 判断Document的符合哪种统计项type
            String _id = document.getString("_id");
            if (_id.endsWith("#menzhenjianchabaogao")) { type = "检查-门诊1"; }
            if (_id.endsWith("#menzhenbinglibaogao")) { type = "检查-门诊2"; }
            if (_id.endsWith("#jianchabaogao")) { type = "检查-住院1"; }
            if (_id.endsWith("#binglibaogao")) { type = "检查-住院2"; }
            if (_id.endsWith("#menzhenjianyanbaogao")) { type = "检验-门诊1"; }
            if (_id.endsWith("#menzhenweishengwujianyan")) { type = "检验-门诊2"; }
            if (_id.endsWith("#jianyanbaogao")) { type = "检验-住院1"; }
            if (_id.endsWith("#weishengwujianyanbaogao")) { type = "检验-住院2"; }
            if (_id.endsWith("#menzhenxiyichufang")) { type = "药品-门诊"; }
            if (_id.endsWith("#yizhu")) { type = "药品-住院"; }
            if (_id.endsWith("#menzhenshoushujilu")) { type = "手术-门诊"; }
            if (_id.endsWith("#shouyeshoushu")) { type = "手术-住院"; }

            // case1 检查-门诊1
            if (type.equals("检查-门诊1")) {
                Document menzhenjianchabaogao = document.get("menzhenjianchabaogao", Document.class);
                List<Document> exam_reports = menzhenjianchabaogao.getList("exam_report", Document.class);
                for (Document exam_report : exam_reports) {
                    String exam_time = exam_report.getString("exam_time");
                    String norm_exam_class_name = exam_report.getString("norm_exam_class_name");
                    if (exam_time == null || norm_exam_class_name == null) {continue;}
                    String time;
                    try {
                        time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(exam_time));
                    } catch (ParseException e) {
                        continue;
                    }
                    String combineKey = time + "#@#检查-门诊#@#" + norm_exam_class_name;
                    combineDataMap.put(combineKey,combineDataMap.getOrDefault(combineKey,0) + 1);
                }
            }

            // case2 检查-门诊2
            if (type.equals("检查-门诊2")) {
                Document menzhenbinglibaogao = document.get("menzhenbinglibaogao", Document.class);
                Document pathology_report = menzhenbinglibaogao.get("pathology_report", Document.class);
                String exam_time = pathology_report.getString("exam_time");
                String norm_exam_class_name = pathology_report.getString("norm_exam_class_name");
                if (exam_time == null || norm_exam_class_name == null) {continue;}
                String time;
                try {
                    time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(exam_time));
                } catch (ParseException e) {
                    continue;
                }
                String combineKey = time + "#@#检查-门诊#@#" + norm_exam_class_name;
                combineDataMap.put(combineKey, combineDataMap.getOrDefault(combineKey, 0) + 1);
            }

            // case3 检查-住院1
            if (type.equals("检查-住院1")) {
                if (document.get("jianchabaogao") instanceof Document) {
                    Document jianchabaogao = document.get("jianchabaogao", Document.class);
                    List<Document> exam_reports = jianchabaogao.getList("exam_report", Document.class);
                    for (Document exam_report : exam_reports) {
                        String exam_time = exam_report.getString("exam_time");
                        String norm_exam_class_name = exam_report.getString("norm_exam_class_name");
                        if (exam_time == null || norm_exam_class_name == null) {
                            continue;
                        }
                        String time;
                        try {
                            time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(exam_time));
                        } catch (ParseException e) {
                            continue;
                        }
                        String combineKey = time + "#@#检查-住院#@#" + norm_exam_class_name;
                        combineDataMap.put(combineKey, combineDataMap.getOrDefault(combineKey, 0) + 1);
                    }
                } else if (document.get("jianchabaogao") instanceof ArrayList) {
                    List<Document> jianchabaogaos = document.get("jianchabaogao", List.class);
                    for (Document jianchabaogao : jianchabaogaos) {
                        Document exam_report = jianchabaogao.get("exam_report", Document.class);
                        String exam_time = exam_report.getString("exam_time");
                        String norm_exam_class_name = exam_report.getString("norm_exam_class_name");
                        if (exam_time == null || norm_exam_class_name == null) {
                            continue;
                        }
                        String time;
                        try {
                            time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(exam_time));
                        } catch (ParseException e) {
                            continue;
                        }
                        String combineKey = time + "#@#检查-住院#@#" + norm_exam_class_name;
                        combineDataMap.put(combineKey, combineDataMap.getOrDefault(combineKey, 0) + 1);
                    }
                }
            }

            // case4 检查-住院2
            if (type.equals("检查-住院2")) {
                Document binglibaogao = document.get("binglibaogao", Document.class);
                Document pathology_report = binglibaogao.get("pathology_report", Document.class);
                String exam_time = pathology_report.getString("exam_time");
                String norm_exam_class_name = pathology_report.getString("norm_exam_class_name");
                if (exam_time == null || norm_exam_class_name == null) {continue;}
                String time;
                try {
                    time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(exam_time));
                } catch (ParseException e) {
                    continue;
                }
                String combineKey = time + "#@#检查-住院#@#" + norm_exam_class_name;
                combineDataMap.put(combineKey, combineDataMap.getOrDefault(combineKey, 0) + 1);
            }

            // case5 检验-门诊1
            if (type.equals("检验-门诊1")) {
                Document menzhenjianyanbaogao = document.get("menzhenjianyanbaogao", Document.class);
                List<Document> lab_reports = menzhenjianyanbaogao.getList("lab_report", Document.class);
                for (Document lab_report : lab_reports) {
                    String report_time = lab_report.getString("report_time");
                    String norm_lab_item_name = lab_report.getString("norm_lab_item_name");
                    if (report_time == null || norm_lab_item_name == null) {continue;}
                    String time;
                    try {
                        time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(report_time));
                    } catch (ParseException e) {
                        continue;
                    }
                    String combineKey = time + "#@#检验-门诊#@#" + norm_lab_item_name;
                    combineDataMap.put(combineKey,combineDataMap.getOrDefault(combineKey,0) + 1);
                }
            }

            // case6 检验-门诊2
            if (type.equals("检验-门诊2")) {
                Document menzhenweishengwujianyan = document.get("menzhenweishengwujianyan", Document.class);
                Document lab_report = menzhenweishengwujianyan.get("lab_report", Document.class);
                String report_time = lab_report.getString("report_time");
                String norm_lab_item_name = lab_report.getString("norm_lab_item_name");
                if (report_time == null || norm_lab_item_name == null) {continue;}
                String time;
                try {
                    time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(report_time));
                } catch (ParseException e) {
                    continue;
                }
                String combineKey = time + "#@#检验-门诊#@#" + norm_lab_item_name;
                combineDataMap.put(combineKey, combineDataMap.getOrDefault(combineKey, 0) + 1);
            }

            // case7 检验-住院1
            if (type.equals("检验-住院1")) {
                Document jianyanbaogao = document.get("jianyanbaogao", Document.class);
                List<Document> lab_reports = jianyanbaogao.getList("lab_report", Document.class);
                for (Document lab_report : lab_reports) {
                    String report_time = lab_report.getString("report_time");
                    String norm_lab_item_name = lab_report.getString("norm_lab_item_name");
                    if (report_time == null || norm_lab_item_name == null) {continue;}
                    String time;
                    try {
                        time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(report_time));
                    } catch (ParseException e) {
                        continue;
                    }
                    String combineKey = time + "#@#检验-住院#@#" + norm_lab_item_name;
                    combineDataMap.put(combineKey,combineDataMap.getOrDefault(combineKey,0) + 1);
                }
            }

            // case8 检验-住院2
            if (type.equals("检验-住院2")) {
                Document weishengwujianyanbaogao = document.get("weishengwujianyanbaogao", Document.class);
                Document lab_report = weishengwujianyanbaogao.get("lab_report", Document.class);
                String report_time = lab_report.getString("report_time");
                String norm_lab_item_name = lab_report.getString("norm_lab_item_name");
                if (report_time == null || norm_lab_item_name == null) {continue;}
                String time;
                try {
                    time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(report_time));
                } catch (ParseException e) {
                    continue;
                }
                String combineKey = time + "#@#检验-住院#@#" + norm_lab_item_name;
                combineDataMap.put(combineKey, combineDataMap.getOrDefault(combineKey, 0) + 1);
            }

            // case9 药品-门诊
            if (type.equals("药品-门诊")) {
                List<Document> menzhenxiyichufangs = document.getList("menzhenxiyichufang", Document.class);
                for (Document menzhenxiyichufang : menzhenxiyichufangs) {
                    String order_begin_time = menzhenxiyichufang.getString("order_begin_time");
                    String china_approved_drug_name = menzhenxiyichufang.getString("china_approved_drug_name");
                    if (order_begin_time == null || china_approved_drug_name == null) {continue;}
                    String time;
                    try {
                        time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(order_begin_time));
                    } catch (ParseException e) {
                        continue;
                    }
                    String combineKey = time + "#@#药品-门诊#@#" + china_approved_drug_name;
                    combineDataMap.put(combineKey,combineDataMap.getOrDefault(combineKey,0) + 1);
                }
            }

            // case10 药品-住院
            if (type.equals("药品-住院")) {
                List<Document> yizhus = document.getList("yizhu", Document.class);
                for (Document yizhu : yizhus) {
                    String order_begin_time = yizhu.getString("order_begin_time");
                    String china_approved_drug_name = yizhu.getString("china_approved_drug_name");
                    if (order_begin_time == null || china_approved_drug_name == null) {continue;}
                    String time;
                    try {
                        time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(order_begin_time));
                    } catch (ParseException e) {
                        continue;
                    }
                    String combineKey = time + "#@#药品-住院#@#" + china_approved_drug_name;
                    combineDataMap.put(combineKey,combineDataMap.getOrDefault(combineKey,0) + 1);
                }
            }

            // case11 手术-门诊
            if (type.equals("手术-门诊")) {
                List<Document> menzhenshoushujilus = document.getList("menzhenshoushujilu", Document.class);
                for (Document menzhenshoushujilu : menzhenshoushujilus) {
                    String operation_time = menzhenshoushujilu.getString("operation_time");
                    String operation_name = menzhenshoushujilu.getString("operation_name");
                    if (operation_time == null || operation_name == null) {continue;}
                    String time;
                    try {
                        time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(operation_time));
                    } catch (ParseException e) {
                        continue;
                    }
                    String combineKey = time + "#@#手术-门诊#@#" + operation_name;
                    combineDataMap.put(combineKey,combineDataMap.getOrDefault(combineKey,0) + 1);
                }
            }

            // case12 手术-住院
            if (type.equals("手术-住院")) {
                List<Document> shouyeshoushus = document.getList("shouyeshoushu", Document.class);
                for (Document shouyeshoushu : shouyeshoushus) {
                    if (!shouyeshoushu.getString("operation_type").equals("手术")) {continue;}
                    String operation_date = shouyeshoushu.getString("operation_date");
                    String operation_name = shouyeshoushu.getString("operation_name");
                    if (operation_date == null || operation_name == null) {continue;}
                    String time;
                    try {
                        time = new SimpleDateFormat("yyyyMMddHH0000").format(new SimpleDateFormat("yyyy-MM-dd HH:mm:dd").parse(operation_date));
                    } catch (ParseException e) {
                        continue;
                    }
                    String combineKey = time + "#@#手术-住院#@#" + operation_name;
                    combineDataMap.put(combineKey,combineDataMap.getOrDefault(combineKey,0) + 1);
                }
            }


        }



    }



    private static MongoClientOptions getOptions() {
        MongoClientOptions.Builder options = new MongoClientOptions.Builder();
        //最小连接数
        options.minConnectionsPerHost(5);
        options.maxConnectionIdleTime(1800000);
        options.maxConnectionLifeTime(1800000);
        options.connectionsPerHost(Integer.parseInt("300"));// 连接池设置为300个连接,默认为100
        options.connectTimeout(Integer.parseInt("3000"));// 连接超时，推荐>3000毫秒
        options.maxWaitTime(Integer.parseInt("5000")); //
        options.socketTimeout(Integer.parseInt("0"));//套接字超时时间，0无限制
        // 线程队列数，如果连接线程排满了队列就会抛出“Out of semaphores to get db”错误。
        options.threadsAllowedToBlockForConnectionMultiplier(Integer.parseInt("5000"));
        /**majority 会出现bug：
         * code=64, message='waiting for replication timed out at shard3', details={ }
         * **/
//            WriteConcern majority = new WriteConcern("majority", 2000, false, true);
        WriteConcern majority = new WriteConcern(1, 2000, false, true);
//            WriteConcern majority = WriteConcern.W1;
        options.writeConcern(majority);
        options.readPreference(ReadPreference.primaryPreferred());
        options.build();
        return options.build();
    }
}
